#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "raylib.h"
#include "pub_lib.h"
#include "FreeImage.h"
#include "image.h"

const int screenWidth = 1024;
const int screenHeight = 768;

char* hint_str = NULL;
cpu_image effect_data;

char left_hint[128] = "image size";

void show_image_fb(FIBITMAP* dib, int startx, int starty)
{
	image_update_frameBuf(dib, effect_data.frame_buf,\
		effect_data.win_width, effect_data.win_height,\
		startx, starty);
}

int init_effect(char* path)
{
	memset(&effect_data, 0, sizeof(cpu_image));
	const char* ext = GetFileExtension(path);

	FIBITMAP* ori;
	ori = open_img(debug_tif_path);
	if (!ori)
		return -1;
	if (!strcmp(ext, ".tif")) {
		read_img(ori, &effect_data);
		if (effect_data.format != PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) {
			printf("only support [0, 255] 1 byte TIF image\n");
			close_img(ori);
			return -1;
		}
	}

	effect_data.ori = (void*)ori;
	//check if need scale
	int max = 360; //最长或最宽不超过360
	int neww = max, newh = max;
	if ( effect_data.image_width > max || effect_data.image_height > max) {
		cal_scaled_val(max, effect_data.image_width, effect_data.image_height,\
				&neww, &newh);
		effect_data.left = FreeImage_Rescale(ori, neww, newh, FILTER_BILINEAR);
	} else {
		effect_data.left = FreeImage_Copy(ori, 0, 0, effect_data.image_width,\
			effect_data.image_height);
	}
	effect_data.image_size = GetPixelDataSize(effect_data.image_width,\
		effect_data.image_height, effect_data.format);
	effect_data.pix_len = get_pixel_bytes(effect_data.image_width,\
		effect_data.image_height, effect_data.image_size);

	//CPU mode
	effect_data.win_width = screenWidth;
	effect_data.win_height = screenHeight;
	effect_data.fb_pixels = effect_data.win_width * effect_data.win_height;
	effect_data.frame_buf = calloc(effect_data.fb_pixels, sizeof(Color));

	//update left_hint[]
	if(effect_data.ori != effect_data.left) {
		sprintf(left_hint, "ori:%d x %d     chg_left:%d x %d",\
			effect_data.image_width, effect_data.image_height,\
			neww, newh);
	} else {
		sprintf(left_hint, "ori:%d x %d",\
			effect_data.image_width, effect_data.image_height);
	}

	return 0;
}

void destroy_effect(void)
{
	free(effect_data.frame_buf);
	close_img(effect_data.ori);
	if(effect_data.left)
		close_img(effect_data.left);
}

void special_effect(int cmd, int startx, int starty)
{
	if(cmd == effect_data.cmd)
		return;

	if(cmd == 1) {
		hint_str = "show original image";
		show_image_fb(effect_data.ori, startx, starty);
		effect_data.cmd = cmd;
	}
	else {
		hint_str = "not support command";
	}
}

int main(int argc, char** argv)
{
	// Initialization
	//--------------------------------------------------------------------------------------
	FreeImage_Initialise(TRUE);

	int ret = init_effect(debug_tif_path);
	if (ret) {
		FreeImage_DeInitialise();
		return -1;
	}

	InitWindow(screenWidth, screenHeight, "demo");
	// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
	SetTargetFPS(60);               // Set our game to run at 60 frames-per-second
	//--------------------------------------------------------------------------------------

	int startx = 10;
	int starty = 30;
	int right_startx = 0;
	int width = FreeImage_GetWidth(effect_data.left);
	right_startx = startx + 20 + width;

	show_image_fb(effect_data.left, startx, starty);
	int right_image_startx = right_startx + 20;
	int right_image_starty = starty;

	int key = 0;
	int change = 0;
	Vector2 mouse = GetMousePosition();
	hint_str = "press a number key";

	// Main game loop
	while (!WindowShouldClose())    // Detect window close button or ESC key
	{
		// Update
		key = GetKeyPressed();
		if (key >= '1' && key <= '9') {
			change = 1;
			key = key - '0';
		}
		else if (key == ESC_KEY) {
			break;
		}

		if (change) {
			change = 0;
			hint_str = "number key pressed";
			special_effect(key, right_image_startx, right_image_starty);
		}
		//----------------------------------------------------------------------------------
		//----------------------------------------------------------------------------------

		// Draw
		//----------------------------------------------------------------------------------
		BeginDrawing();
		ClearBackground(RAYWHITE);

		DrawText(left_hint, startx, 5, 20, BLACK);
		if (hint_str) {
			DrawText(hint_str, right_image_startx, 0, 20, BLACK);
		}
		DrawLine(right_startx, starty, right_startx, GetScreenHeight(), GRAY);
		draw_image(effect_data.frame_buf,\
			effect_data.win_width, effect_data.win_height);

		mouse = GetMousePosition();
		DrawText(TextFormat("mouse(%d, %d)", (int)mouse.x, (int)mouse.y), \
			GetScreenWidth() - 240, GetScreenHeight() - 50, 20, BLACK);

		EndDrawing();
		//----------------------------------------------------------------------------------
	}

	// De-Initialization
	destroy_effect();
	FreeImage_DeInitialise();

	//--------------------------------------------------------------------------------------
	CloseWindow();        // Close window and OpenGL context
	//--------------------------------------------------------------------------------------

	return 0;
}


